package com.me.jingdongshop.ui.view;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

/**
 * @author admin
 * 【我的订单】详情页：滑动删除item
 */
public class SwipeLayout extends ViewGroup {

    /** 菜单布局 */
    private View menuView;
    /** 内容布局 */
    private View contentView;

    private int mHeight;
    private int mWidth;

    /** 菜单界面的宽度 */
    private int menuWidth;
    private ViewDragHelper dragHelper;

    public SwipeLayout(@NonNull Context context) {
        super(context);
        init();
    }

    public SwipeLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    // 4. 处理回调方法
    ViewDragHelper.Callback mCallback = new ViewDragHelper.Callback() {

        // 返回true，子控件才可以实现拖动
        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            return true;
        }

        // 设置子控件水平方向将要显示的位置
        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            // 限制contentView滑动的范围:[-menuWidth, 0]
            if (child == contentView) {
                if (left < -menuWidth) {  // 左边界
                    left = -menuWidth;
                } else if (left > 0) {
                    left = 0;
                }
            }

            // 限制menuView滑动的范围:   [mWidth - menuWidth, mWidth]
            if (child == menuView) {
                if (left < mWidth - menuWidth) {  // 左边界
                    left = mWidth - menuWidth;
                } else if (left > mWidth) {
                    left = mWidth;
                }
            }
            return left;
        }

        // 位置发生时回调： 关联子控件的滑动
        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
            super.onViewPositionChanged(changedView, left, top, dx, dy);

            // 当滑动内容界面时，同时滑动菜单界面，且两者滑动的偏移量一样
            if (changedView == contentView) {
                menuView.offsetLeftAndRight(dx);
            }

            // 当滑动菜单界面时，同时滑动内容界面，且两者滑动的偏移量一样
            if (changedView == menuView) {
                contentView.offsetLeftAndRight(dx);
            }

            // 主动刷新界面，解决菜单界面空白的问题
            invalidate();

            // if (左右滑动SwipeLayout)
            //     则禁止列表上下滑动
            if (Math.abs(dx) >= Math.abs(dy)) {
                // 请求父控件(也就是列表)不要拦截处理触摸事件，则列表无法上下滑动
                requestDisallowInterceptTouchEvent(true);
            }
        }

        // 拖动结束，松开手时回调:  打开或关闭侧滑删除控件
        // xvel: 松开手时水平方向的速度, 往右滑为正值
        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            super.onViewReleased(releasedChild, xvel, yvel);

            if (xvel < 0) {  // 用户往左甩
                open();
            } else if (xvel == 0 && releasedChild.getLeft() < -menuWidth / 2) {
                // 中线左边速度为0松开手
                open();
            } else {
                close();
            }
        }
    };

    public void open() {
        // contentView.layout(-menuWidth, 0, mWidth-menuWidth, mHeight);

        // 平滑打开
        // 平滑地移动某个子控件到某个位置
        dragHelper.smoothSlideViewTo(contentView, -menuWidth, 0);
        // 刷新控件
        ViewCompat.postInvalidateOnAnimation(this);

        // 记录当前打开的SwipeLayout
        SwipeLayoutManager.getInstance().saveOpenSwipeLayout(this);
    }

    public void close() {
        // contentView.layout(0, 0, mWidth, mHeight);
        // 平滑关闭
        dragHelper.smoothSlideViewTo(contentView, 0, 0);
        // 刷新控件
        ViewCompat.postInvalidateOnAnimation(this);

        // 清空列表中打开的SwipeLayout
        SwipeLayoutManager.getInstance().clearSwipeLayout();
    }

    @Override
    public void computeScroll() {
        super.computeScroll();

        if (dragHelper.continueSettling(true)) {
            // 刷新控件
            ViewCompat.postInvalidateOnAnimation(this);
        }
    }

    private void init() {
        // 1. 创建ViewDragHelper对象
        dragHelper = ViewDragHelper.create(this, mCallback);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // 2. 由dragHelper决定是否拦截事件
        return dragHelper.shouldInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        // if (用户按下 && 列表已经打开了一个SwipeLayout)
        //    则关闭上一次打开的SwipeLayout
        if (event.getAction() == MotionEvent.ACTION_DOWN
                && SwipeLayoutManager.getInstance().hasOpenSwipeLayout()
                // 要打开的SwipeLayout与当前打开的为同一个时，不关闭
                && this != SwipeLayoutManager.getInstance().getOpenSwipeLayout()) {

            // 关闭上一次打开的SwipeLayout
            SwipeLayoutManager.getInstance().closeOpenSwipeLayout();

            // 请求父控件（ListView）不要拦截事件，把触摸事件传到子控件
            // 这样，因为ListView不处理触摸事件，所以就无法上下滚动了
            requestDisallowInterceptTouchEvent(true);

            // 不把按下事件传给ViewDragHelper，这样SwipeLayout就无法左右滑动了
            // 因为ViewDragHelper缺少down事件
            return true;
        }

        // 3. 由dragHelper处理触摸事件
        dragHelper.processTouchEvent(event);

        // 按下时需要返回true，才能接收到后续的move和up事件
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            return true;
        }

        return super.onTouchEvent(event);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        if (getChildCount() < 2) {
            throw new IllegalStateException("SwipeLayout至少要有两个子控件");
        }

        // 获取两个子控件
        menuView = getChildAt(0);
        contentView = getChildAt(1);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        // 注意：继承ViewGroup时，需要主动测量布局的子控件
        for (int i = 0; i < getChildCount(); i++) {
            measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec);
        }

        // 获取控件的宽高
        mHeight = getMeasuredHeight();
        mWidth = getMeasuredWidth();

        // 菜单界面的宽度
        menuWidth = menuView.getMeasuredWidth();
    }

//    // 在此方法获取控件尺寸也可以
//    @Override
//    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
//        super.onSizeChanged(w, h, oldw, oldh);
//
//        // 获取控件的宽高
//        mHeight = getMeasuredHeight();
//        mWidth = getMeasuredWidth();
//        // 菜单界面的宽度
//        menuWidth = menuView.getMeasuredWidth();
//    }

    // 设置子控件显示的位置
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        // super.onLayout(changed, left, top, right, bottom);

        contentView.layout(0, 0, mWidth, mHeight);
        menuView.layout(mWidth, 0, mWidth + menuWidth, mHeight);
    }
}











